namespace OX.Strongbind.Dynamic
{
    using Castle.Core.Interceptor;
    using System;
    using System.Collections.Generic;
    using System.Text; 

    internal class DynamicProxyInterceptor : IInterceptor
    {
        private Guid identity;
        private DynamicProxyGenerator proxyGenerator;
        private IPropertyAccessNotifier notifier;
        private string navigationPath;

        public DynamicProxyInterceptor(DynamicProxyGenerator generator, Guid identity, IPropertyAccessNotifier notifier)
        {
            this.identity = identity;
            this.navigationPath = notifier.GetLastNavigationPath();
            this.notifier = notifier;
            proxyGenerator = generator;
        }

        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.ReturnType.IsValueType)
                invocation.ReturnValue = Activator.CreateInstance(invocation.Method.ReturnType);
            else
                invocation.ReturnValue = null;

            if (!MethodMatchHelper.IsGetter(invocation.Method))
                return;

            string propertyName = MethodMatchHelper.PropertyNameFromGetter(invocation.Method);
            notifier.NotifyGetProperty(identity, string.IsNullOrEmpty(navigationPath) ? propertyName : string.Format("{0}.{1}", navigationPath, propertyName));

            // Proxy the return value as well to support navigation path bindings
            try
            {
                // Child proxies use the identity of their roots
                invocation.ReturnValue = proxyGenerator.For(invocation.Method.ReturnType, identity, notifier);
            }
            catch
            {
                // Create a default instance
                try
                {
                    invocation.ReturnValue = Activator.CreateInstance(invocation.Method.ReturnType);
                }
                catch
                {
                    invocation.ReturnValue = null;
                }
            }
        }
    }
}
